﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Vehicle : MonoBehaviour {
    public Dictionary<string, SteerBase> m_dicSteers;
    public SteerBase[] m_Steers;
    public float m_fMaxSpeed = 10;
    public float m_fMaxForce = 100;
    public float m_fMass = 1;
    //速度
    public Vector3 m_v3Velocity;
    //合力
    public Vector3 m_v3Forces;
    //加速度
    public Vector3 m_v3Acceleration;
    //摩擦力,当没有力作用在身上的时候去归零速度
    public float m_fDamping = 1;
    //转向的角速度
    public float m_fRotation = 1;
    public float m_fIgnoreRotation = 0.2f;
    //范围盒子
    private GroupRadar m_pRadar;
    //缸体
    private Rigidbody m_pRigidbody;
    //碰撞体
    private SphereCollider m_pCollider;


    public List<GameObject> Neighbors
    {
        get
        {
            if (m_pRadar == null)
                return null;
            else
                return m_pRadar.GetNeighbors();
        }
    }

    public Vector3 Postion
    {
        get { return transform.position; }
    }

    public Vector3 Forward
    {
        get { return transform.forward; }
    }

    public void Init(float m_fRadar)
    {
        m_pRadar = GetComponent<GroupRadar>();
        if (m_pRadar == null)
            m_pRadar = gameObject.AddComponent<GroupRadar>();
        m_pRadar.m_fRadius = m_fRadar;
        m_pRadar.layerChecked = LayerMask.GetMask(new string[] { BattleDef.LayerName_3dObj });


        m_pRigidbody = GetComponent<Rigidbody>();
        if (m_pRigidbody == null)
            m_pRigidbody = gameObject.AddComponent<Rigidbody>();
        m_pRigidbody.mass = 1;
        m_pRigidbody.isKinematic = true;
        m_pRigidbody.useGravity = false;
        m_pCollider = GetComponent<SphereCollider>();
        if (m_pCollider == null)
            m_pCollider = gameObject.AddComponent<SphereCollider>();
        m_pCollider.center = new Vector3(0, 0.5f, 0);
        m_pCollider.radius = 0.5f;
        m_pCollider.isTrigger = true;

        GetSteers();
        if (m_dicSteers == null)
            m_dicSteers = new Dictionary<string, SteerBase>();
        m_dicSteers.Clear();

        for (int i = 0; i < m_Steers.Length; i++)
        {
            if (!m_dicSteers.ContainsKey(m_Steers[i].CName))
            {
                m_dicSteers.Add(m_Steers[i].CName, m_Steers[i]);
            } 
        }
        m_fMass = 0.8f + Random.Range(0, 0.5f);
        m_fMaxSpeed = 8.0f + Random.Range(0, 2f);
    }

    public void GetSteers()
    {
        m_Steers = GetComponents<SteerBase>();
        for (int i = 0; i < m_Steers.Length; i++)
        {
            m_Steers[i].Init(this);
        }
    }

    public void CalculateForces()
    {
        m_v3Forces = Vector3.zero;
        for (int i = 0; i < m_Steers.Length; i++)
        {
            if (m_Steers[i].enabled)
            {
                m_v3Forces += m_Steers[i].Force * m_Steers[i].Weight;
            }
        }
        m_v3Forces = Vector3.ClampMagnitude(m_v3Forces, m_fMaxForce);
        m_v3Acceleration = m_v3Forces / m_fMass;
    }

    public void UpdatePos(float deltaTime)
    {
        m_v3Velocity = m_v3Velocity + m_v3Acceleration * deltaTime;
        m_v3Velocity = Vector3.ClampMagnitude(m_v3Velocity, m_fMaxSpeed);
        if (m_v3Forces.Equals(Vector3.zero))
        {
            m_v3Velocity = Vector3.zero;
        }


        transform.position += m_v3Velocity * deltaTime;
        //转向
        if (m_v3Velocity.magnitude > m_fIgnoreRotation)
        {
            transform.forward = Vector3.Slerp(transform.forward, m_v3Velocity, m_fRotation * deltaTime);
        }
    }

    public void FreshRadar()
    {
        if(m_pRadar != null)
        {
            m_pRadar.FreshNeighbors();
        }
    }

    public void SetSteerState(string cName,bool state)
    {
        if (m_dicSteers.ContainsKey(cName) && m_dicSteers[cName].enabled != state)
        {
            m_dicSteers[cName].enabled = state;
        }
    }

    public void SetSteerForPoint(Vector3 point,System.Action<SteerBase> onArrival)
    {
        SetSteerState(SteerName.StN_SteerForPoint, true);
        SteerForPoint steer = m_dicSteers[SteerName.StN_SteerForPoint] as SteerForPoint;
        steer.OnArrival = onArrival;
        steer.TagPoint = point;
    }

    public void CloseAllSteer()
    {
        for (int i = 0; i < m_Steers.Length; i++)
        {
            SetSteerState(m_Steers[i].CName, false);
        }
    }

    public void StopForce()
    {
        m_v3Forces = Vector3.zero;
        m_v3Velocity = Vector3.zero;
    }
}
